<?php

// This file is part of CorrectWriting question type - https://code.google.com/p/oasychev-moodle-plugins/
//
// CorrectWriting question type is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// CorrectWriting is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with CorrectWriting.  If not, see <http://www.gnu.org/licenses/>.

/**
 * Unit tests for string editions of Visualisator
 *
 * @package    questions
 * @copyright  2012 Oleg Sychev, Volgograd State Technical University
 * @author     Dmitriy Matyushechkin <dima_kekc@mail.ru>
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */

global $CFG;  
require_once($CFG->dirroot.'/question/type/correctwriting/drawing_picture_visualisator.php');


/**
  * This class contains the test cases for drawing picture functions.
  */
 class qtype_correctwriting_drawing_picture_test extends PHPUnit_Framework_TestCase {
 	    // Tests for getting result string function
    public function test_get_result_insert_front() {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = 'abcdef';
        $stringoperations[] = 'insert:0:0:R';

        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string ($lexems, $objectoperations);
        $this->assertTrue($lexems[0] == 'Rabcdef');
    }

    public function test_get_result_insert_double() {
       
       $lexems = array ();
       $stringoperations = array();
       $objectoperations = array ();

       $lexems[] = 'abcdef';
       $stringoperations[] = 'insert:0:2:R';
       $stringoperations[] = 'insert:0:2:T';

       $objectoperations = qtype_correctwriting_get_objects($stringoperations);
       $lexems = qtype_correctwriting_get_result_string ($lexems, $objectoperations);

       $this->assertTrue($lexems[0] == 'abTRcdef');
    }

    public function test_get_result_insert_complex() {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = 'abcdef';
        $stringoperations[] = 'insert:0:2:R';
        $stringoperations[] = 'insert:0:2:T';
        $stringoperations[] = 'insert:0:0:I';
        $stringoperations[] = 'insert:0:0:K';
           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);

        $this->assertTrue($lexems[0] == 'KIabTRcdef');
    }

    public function test_get_result_delete_front () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = 'abcdef';
        $stringoperations[] = 'delete:0:0';
                   
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);

        $this->assertTrue($lexems[0] == 'bcdef');
    }

    public function test_get_result_delete_double () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = 'abcdef';
        $stringoperations[] = 'delete:0:1';
        $stringoperations[] = 'delete:0:1';
                   
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);

        $this->assertTrue($lexems[0] == 'adef');
    }

    public function test_get_result_delete_all () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = 'abc';
        $stringoperations[] = 'delete:0:1';
        $stringoperations[] = 'delete:0:1';
        $stringoperations[] = 'delete:0:0';
                   
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);

        $this->assertTrue($lexems[0] == '');
    }

    public function test_get_result_insertlexem_single () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = 'abc';
        $lexems[] = 'def';
        $stringoperations[] = 'insertlexem:1:123';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);

        $this->assertTrue($lexems[0] == 'abc' && $lexems[1] == '123' && $lexems[2] == 'def' && count($lexems) == 3);
    }

    public function test_get_result_insertlexem_double () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = 'abc';
        $stringoperations[] = 'insertlexem:1:123';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);

        $this->assertTrue($lexems[0] == 'abc' && $lexems[1] == '123' && count($lexems) == 2);
    }

    public function test_get_result_insertlexem_to_empty () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = '';
        $stringoperations[] = 'insertlexem:0:123';
        $stringoperations[] = 'insertlexem:0:345';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);

        $this->assertTrue($lexems[0] == '345' && $lexems[1] == '123');
    }

    public function test_get_result_deletelexem_middle () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = '123';
        $lexems[] = '456';
        $lexems[] = '789';
        $stringoperations[] = 'deletelexem:1';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);        

        $this->assertTrue($lexems[0] == '123');
        $this->assertTrue($lexems[1] == '789');
        $this->assertTrue(count($lexems) == 2);
    }

    public function test_get_result_deletelexem_double () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = '123';
        $lexems[] = '456';
        $lexems[] = '789';
        $stringoperations[] = 'deletelexem:1';
        $stringoperations[] = 'deletelexem:1';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);

        $this->assertTrue($lexems[0] == '123');
        $this->assertTrue(count($lexems) == 1);
    }

    public function test_get_result_deletelexem_toempty () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = '123';
        $lexems[] = '456';
        $lexems[] = '789';
        $stringoperations[] = 'deletelexem:1';
        $stringoperations[] = 'deletelexem:1';
        $stringoperations[] = 'deletelexem:0';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);
        
        $this->assertTrue(count($lexems) == 0);
    }

    public function test_get_result_move_middle () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = '123456789';
        $stringoperations[] = 'move:0:1:4';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);

        $this->assertTrue($lexems[0] == '134256789');
    }

    public function test_get_result_move_double_to_one_pos () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = '123456789';
        $stringoperations[] = 'move:0:1:4';
        $stringoperations[] = 'move:0:1:4';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);
        
        $this->assertTrue($lexems[0] == '142356789');
    }

    public function test_get_result_move_double_criss_cross () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = '123456789';
        $stringoperations[] = 'move:0:1:6';
        $stringoperations[] = 'move:0:7:3';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);
        
        $this->assertTrue($lexems[0] == '134856279');
    }

    public function test_get_result_movelexem_middle () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = '1234';
        $lexems[] = '56789';
        $lexems[] = 'abcde';
        $stringoperations[] = 'movelexem:0:2';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);

        $this->assertTrue($lexems[0] == '56789');
        $this->assertTrue($lexems[1] == '1234');
        $this->assertTrue($lexems[2] == 'abcde');
    }

    public function test_get_result_movelexem_same_place () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = '1234';
        $lexems[] = '56789';
        $lexems[] = 'abcde';
        $stringoperations[] = 'movelexem:0:1';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);
       
        $this->assertTrue($lexems[0] == '1234');
        $this->assertTrue($lexems[1] == '56789');
        $this->assertTrue($lexems[2] == 'abcde');
    }

    public function test_get_result_movelexem_criss_cross () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = '1234';
        $lexems[] = '56789';
        $lexems[] = 'abcde';
        $lexems[] = 'XYZ';
        $stringoperations[] = 'movelexem:0:2';
        $stringoperations[] = 'movelexem:3:0';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);        
        
        $this->assertTrue($lexems[0] == 'XYZ');
        $this->assertTrue($lexems[1] == '56789');
        $this->assertTrue($lexems[2] == '1234');
        $this->assertTrue($lexems[3] == 'abcde');
    }

    public function test_get_result_space_middle () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = '1234567';
        $stringoperations[] = 'space:0:4';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);        
        
        $this->assertTrue($lexems[0] == '1234');
        $this->assertTrue($lexems[1] == '567');
        $this->assertTrue(count($lexems) == 2);
    }

    public function test_get_result_space_double () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = '1234567';
        $stringoperations[] = 'space:0:4';
        $stringoperations[] = 'space:1:1';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);
        
        $this->assertTrue($lexems[0] == '1234');
        $this->assertTrue($lexems[1] == '5');
        $this->assertTrue($lexems[2] == '67');
        $this->assertTrue(count($lexems) == 3);
    }

    public function test_get_result_deletespace () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = '1234';
        $lexems[] = '5678';
        $stringoperations[] = 'deletespace:1';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);
        
        $this->assertTrue($lexems[0] == '12345678');
        $this->assertTrue(count($lexems) == 1);
    }

    public function test_get_result_deletespace_double () {
    	$lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = '1234';
        $lexems[] = '5678';
        $lexems[] = 'abcde';
        $stringoperations[] = 'deletespace:1';
        $stringoperations[] = 'deletespace:1';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);
        
        $this->assertTrue($lexems[0] == '12345678abcde');
    }

    public function test_get_result_change () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = '1234';
        $stringoperations[] = 'change:0:2:U';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);

        $this->assertTrue($lexems[0] == '12U4');
    }

    public function test_get_result_changelexem () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = '1234';
        $lexems[] = 'abcde';
        $stringoperations[] = 'changelexem:1:567';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);
        
        $this->assertTrue($lexems[0] == '1234');
        $this->assertTrue($lexems[1] == '567');
    }

    public function test_get_result_exchange () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = '1234';
        $stringoperations[] = 'exchange:0:1';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);
        
        $this->assertTrue($lexems[0] == '1324');
    }

    public function test_get_result_exchange_neighbour () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = '1234';
        $stringoperations[] = 'exchange:0:1';
        $stringoperations[] = 'exchange:0:2';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);
        
        $this->assertTrue($lexems[0] == '1342');
    }

    public function test_get_result_complex_one_lexem () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = '123456789';
        $stringoperations[] = 'exchange:0:1';
        $stringoperations[] = 'insert:0:4:I';
        $stringoperations[] = 'delete:0:0';
        $stringoperations[] = 'insert:0:4:j';
        $stringoperations[] = 'move:0:2:6';
        $stringoperations[] = 'delete:0:6';
        $stringoperations[] = 'delete:0:6';
        $stringoperations[] = 'change:0:7:A';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);
        
        $this->assertTrue($lexems[0] == '32Ij548A');
    }

    public function test_get_result_complex_between_lexems () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = 'abcdefg';
        $lexems[] = '1234';
        $lexems[] = 'XYZ';
        $stringoperations[] = 'space:0:2';
        $stringoperations[] = 'movelexem:2:1';
        $stringoperations[] = 'insertlexem:1:HiJ';
        $stringoperations[] = 'deletelexem:0';
        $stringoperations[] = 'changelexem:3:!';
                           
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);
        
        $this->assertTrue($lexems[0] == 'HiJ');
        $this->assertTrue($lexems[1] == '1234');
        $this->assertTrue($lexems[2] == 'cdefg');
        $this->assertTrue($lexems[3] == '!');
    }

    public function test_get_result_complex_total () {
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $lexems[] = 'abcdefg';
        $lexems[] = '12345678';
        $lexems[] = 'UVWXYZ';
        $stringoperations[] = 'space:0:2';
        $stringoperations[] = 'exchange:0:0';
        $stringoperations[] = 'changelexem:3:hello';
        $stringoperations[] = 'delete:1:2';
        $stringoperations[] = 'delete:1:2';
        $stringoperations[] = 'deletespace:2';
        $stringoperations[] = 'move:1:0:8';
        $stringoperations[] = 'move:1:9:2';
        $stringoperations[] = 'insert:1:6:V';
        $stringoperations[] = 'insert:1:7:i';
        $stringoperations[] = 'movelexem:0:2';
        $stringoperations[] = 'change:0:4:6';
                          
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string($lexems, $objectoperations);
        
        $this->assertTrue($lexems[0] == 'dg7163Vi45c68');
        $this->assertTrue($lexems[1] == 'ba');
        $this->assertTrue($lexems[2] == 'hello');
    }

    //tests for recount_indexes function
    public function test_recount_insert_different_places () {
    	$lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $work = array();
        $lexems[] = '123';
        $lexems[] = 'abc';
        $stringoperations[] = 'insert:0:2:T';
        $stringoperations[] = 'insert:1:1:T';

        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $work = qtype_correctwriting_recount_indexes ($objectoperations, $lexems);
        
        $this->assertTrue($work[0]->posinpicture == 0);
        $this->assertTrue($work[0]->lexem == 0);
        $this->assertTrue($work[1]->posinpicture == 1);
        $this->assertTrue($work[1]->lexem == 0);
        $this->assertTrue($work[2]->posinpicture == 2);
        $this->assertTrue($work[2]->lexem == 0);
        $this->assertTrue($work[3]->posinpicture == 2);
        $this->assertTrue($work[3]->lexem == 0);
        $this->assertTrue($work[4]->lexem == 1);
        $this->assertTrue($work[4]->posinpicture == 0);
        $this->assertTrue($work[5]->lexem == 1);
        $this->assertTrue($work[5]->posinpicture == 1);
        $this->assertTrue($work[6]->lexem == 1);
        $this->assertTrue($work[6]->posinpicture == 1);
        $this->assertTrue($work[7]->lexem == 1);
        $this->assertTrue($work[7]->posinpicture == 2);
    }

    public function test_recount_single_insertlexem () {
    	$lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $work = array();
        $lexems[] = '123';
        $lexems[] = 'abc';
        $stringoperations[] = 'insertlexem:1:456';

        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $work = qtype_correctwriting_recount_indexes ($objectoperations, $lexems);

        $this->assertTrue($work[0]->posinpicture == 0);
        $this->assertTrue($work[0]->lexem == 0);
        $this->assertTrue($work[1]->posinpicture == 1);
        $this->assertTrue($work[1]->lexem == 0);
        $this->assertTrue($work[2]->posinpicture == 2);
        $this->assertTrue($work[2]->lexem == 0);
        $this->assertTrue($work[3]->lexem == 1);
        $this->assertTrue($work[4]->lexem == 1);
        $this->assertTrue($work[5]->lexem == 1);
        $this->assertTrue($work[6]->lexem == 2);
        $this->assertTrue($work[7]->lexem == 2);
        $this->assertTrue($work[3]->operationname == 'insertlexem');
        $this->assertTrue($work[3]->symbols == '456');
    }

    public function test_recount_delete_different_places () {
    	$lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $work = array();
        $lexems[] = '123';
        $lexems[] = 'abc';
        $stringoperations[] = 'delete:0:2';
        $stringoperations[] = 'delete:1:0';

        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $work = qtype_correctwriting_recount_indexes ($objectoperations, $lexems);

        $this->assertTrue($work[0]->posinpicture == 0);
        $this->assertTrue($work[0]->lexem == 0);
        $this->assertTrue($work[1]->posinpicture == 1);
        $this->assertTrue($work[1]->lexem == 0);
        $this->assertTrue($work[2]->posinpicture == 2);
        $this->assertTrue($work[2]->lexem == 0);
        $this->assertTrue($work[3]->posinpicture == 0);
        $this->assertTrue($work[3]->lexem == 1);
        $this->assertTrue($work[4]->lexem == 1);
        $this->assertTrue($work[4]->posinpicture == 1);
        $this->assertTrue($work[5]->lexem == 1);
        $this->assertTrue($work[5]->posinpicture == 2);
        $this->assertTrue($work[2]->countable == false);
        $this->assertTrue($work[3]->countable == false);
        $this->assertTrue($work[2]->operationname == 'delete');
        $this->assertTrue($work[3]->operationname == 'delete');
    }

    public function test_recount_deletelexem () {
    	$lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $work = array();
        $lexems[] = 'a';
        $lexems[] = '12';
        $lexems[] = 'abc';
        $stringoperations[] = 'deletelexem:1';

        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $work = qtype_correctwriting_recount_indexes ($objectoperations, $lexems);

        $this->assertTrue($work[0]->posinpicture == 0);
        $this->assertTrue($work[0]->lexem == 0);
        $this->assertTrue($work[1]->lexem == -1);
        $this->assertTrue($work[2]->lexem == -1);
        $this->assertTrue($work[3]->lexem == 1);
        $this->assertTrue($work[4]->lexem == 1);
        $this->assertTrue($work[5]->lexem == 1);
        $this->assertTrue($work[1]->countable == false);
        $this->assertTrue($work[2]->countable == false);
        $this->assertTrue($work[1]->operationname == 'deletelexem');
    } 

    public function test_recount_move () {
    	$lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $work = array();
        $lexems[] = 'abcde';
        $stringoperations[] = 'move:0:1:3';

        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $work = qtype_correctwriting_recount_indexes ($objectoperations, $lexems);

        $this->assertTrue($work[0]->posinpicture == 0);
        $this->assertTrue($work[0]->lexem == 0);
        $this->assertTrue($work[1]->lexem == 0);
        $this->assertTrue($work[1]->posinpicture == 1);
        $this->assertTrue($work[1]->operationname == 'move');
        $this->assertTrue($work[1]->lexemto == 0);
        $this->assertTrue($work[1]->countable == false);
        $this->assertTrue($work[1]->ID == 1);
        $this->assertTrue($work[2]->lexem == 0);
        $this->assertTrue($work[2]->posinpicture == 2);
        $this->assertTrue($work[3]->lexem == 0);
        $this->assertTrue($work[3]->posinpicture == 3);
        $this->assertTrue($work[3]->operationname == 'dest');
        $this->assertTrue($work[3]->ID == 1);
        $this->assertTrue($work[4]->lexem == 0);
        $this->assertTrue($work[4]->posinpicture == 3);
        $this->assertTrue($work[5]->lexem == 0);
        $this->assertTrue($work[5]->posinpicture == 4);
    }

    public function test_recount_movelexem () {
    	$lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $work = array();
        $lexems[] = 'ab';
        $lexems[] = 'cde';
        $lexems[] = 'fgh';
        $stringoperations[] = 'movelexem:0:2';

        $source = $lexems;
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string ($lexems, $objectoperations);
        $work = qtype_correctwriting_recount_indexes ($objectoperations, $source);

        $this->assertTrue($work[0]->posinpicture == 0);
        $this->assertTrue($work[0]->lexem == -1);
        $this->assertTrue($work[1]->posinpicture == 1);
        $this->assertTrue($work[1]->lexem == -1);
        $this->assertTrue($work[2]->posinpicture == 0);
        $this->assertTrue($work[2]->lexem == 0);
        $this->assertTrue($work[3]->posinpicture == 1);
        $this->assertTrue($work[3]->lexem == 0);
        $this->assertTrue($work[4]->posinpicture == 2);
        $this->assertTrue($work[4]->lexem == 0);
        $this->assertTrue($work[5]->lexeminpicture == 2);
        $this->assertTrue($work[5]->lexem == 1);
        $this->assertTrue($work[6]->lexeminpicture == 2);
        $this->assertTrue($work[6]->lexem == 1);
        $this->assertTrue($work[7]->posinpicture == 0);
        $this->assertTrue($work[7]->lexem == 2);
        $this->assertTrue($work[8]->posinpicture == 1);
        $this->assertTrue($work[8]->lexem == 2);
        $this->assertTrue($work[9]->posinpicture == 2);
        $this->assertTrue($work[9]->lexem == 2);
        $this->assertTrue($work[10]->lexem == 3);

        $this->assertTrue($work[0]->operationname == 'movelexem');
        $this->assertTrue($work[0]->lexemto == 2);
        $this->assertTrue($work[0]->ID == 1);
        $this->assertTrue($work[0]->countable == false);
        $this->assertTrue($work[1]->countable == false);
        $this->assertTrue($work[5]->operationname == 'insertlexem');
        $this->assertTrue($work[5]->symbols == 'ab');
        $this->assertTrue($work[5]->countable == true);
        $this->assertTrue($work[6]->operationname == 'dest');
        $this->assertTrue($work[6]->symbols == 'ab');
        $this->assertTrue($work[6]->countable == true);
    }   

    public function test_recount_space () {
    	$lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $work = array();
        $lexems[] = 'abcd';
        $stringoperations[] = 'space:0:2';

        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $work = qtype_correctwriting_recount_indexes ($objectoperations, $lexems);

        $this->assertTrue($work[0]->posinpicture == 0);
        $this->assertTrue($work[0]->lexem == 0);
        $this->assertTrue($work[1]->posinpicture == 1);
        $this->assertTrue($work[1]->lexem == 0);
        $this->assertTrue($work[2]->posinpicture == 2);
        $this->assertTrue($work[2]->lexem == 0);
        $this->assertTrue($work[2]->operationname == 'space');
        $this->assertTrue($work[2]->countable == false);
        $this->assertTrue($work[3]->lexem == 1);
        $this->assertTrue($work[3]->posinpicture == 2);
        $this->assertTrue($work[4]->lexem == 1);
        $this->assertTrue($work[4]->posinpicture == 3);
    }

    public function test_recount_change () {
    	$lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $work = array();
        $lexems[] = 'abc';
        $stringoperations[] = 'change:0:1:T';

        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $work = qtype_correctwriting_recount_indexes ($objectoperations, $lexems);

        $this->assertTrue($work[0]->posinpicture == 0);
        $this->assertTrue($work[0]->lexem == 0);
        $this->assertTrue($work[1]->posinpicture == 1);
        $this->assertTrue($work[1]->lexem == 0);
        $this->assertTrue($work[2]->posinpicture == 2);
        $this->assertTrue($work[2]->lexem == 0);
        $this->assertTrue($work[1]->operationname == 'change');
        $this->assertTrue($work[1]->placeto == 1);
        $this->assertTrue($work[1]->symbols == 'T');
        $this->assertTrue($work[3]->operationname == 'last');
    }

    public function test_recount_changelexem () {
    	$lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $work = array();
        $lexems[] = 'a';
        $lexems[] = '12';
        $lexems[] = 'a';
        $stringoperations[] = 'changelexem:1:abcd';

        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $work = qtype_correctwriting_recount_indexes ($objectoperations, $lexems);

        $this->assertTrue($work[0]->lexem == 0);
        $this->assertTrue($work[1]->lexem == 1);
        $this->assertTrue($work[2]->lexem == 1);
        $this->assertTrue($work[3]->lexem == 2);
        $this->assertTrue($work[1]->operationname == 'changelexem');
        $this->assertTrue($work[1]->symbols == 'abcd');
    }

    public function test_recount_deletespace () {
    	$lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $work = array();
        $lexems[] = 'a';
        $lexems[] = '12';

        $stringoperations[] = 'deletespace:1';

        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $work = qtype_correctwriting_recount_indexes ($objectoperations, $lexems);

        $this->assertTrue($work[0]->lexem == 0);
        $this->assertTrue($work[1]->lexem == 0);
        $this->assertTrue($work[2]->lexem == 0);
        $this->assertTrue($work[1]->operationname == 'deletespace');
    }
            

    public function test_recount_complex () {
    	$lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $work = array();
        $lexems[] = 'abc';
        $lexems[] = 'def';
        $lexems[] = '123';

        $stringoperations[] = 'space:1:1';
        $stringoperations[] = 'deletelexem:0';
        $stringoperations[] = 'insertlexem:1:re';
        $stringoperations[] = 'movelexem:3:2';

        $source = $lexems;
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string ($lexems, $objectoperations);
        $work = qtype_correctwriting_recount_indexes ($objectoperations, $source);

        $this->assertTrue($work[0]->lexem == -1);
        $this->assertTrue($work[0]->operationname == 'deletelexem');
        $this->assertTrue($work[0]->countable == false);
        $this->assertTrue($work[1]->lexem == -1);
        $this->assertTrue($work[1]->countable == false);
        $this->assertTrue($work[2]->lexem == -1);
        $this->assertTrue($work[2]->countable == false);
        $this->assertTrue($work[3]->lexem == 0);
        $this->assertTrue($work[4]->lexem == 0);
        $this->assertTrue($work[4]->operationname == 'space');
        $this->assertTrue($work[4]->countable == false);
        $this->assertTrue($work[5]->lexem == 1);
        $this->assertTrue($work[5]->operationname == 'insertlexem');
        $this->assertTrue($work[5]->symbols == 're');
        $this->assertTrue($work[6]->lexem == 1);
        $this->assertTrue($work[7]->lexem == 2);
        $this->assertTrue($work[7]->operationname == 'insertlexem');
        $this->assertTrue($work[7]->symbols == '123');
        $this->assertTrue($work[8]->lexem == 2);
        $this->assertTrue($work[9]->lexem == 2);
        $this->assertTrue($work[10]->lexem == 3);
        $this->assertTrue($work[11]->lexem == 3);
        $this->assertTrue($work[12]->lexem == -1);
        $this->assertTrue($work[12]->operationname == 'movelexem');
        $this->assertTrue($work[12]->countable == false);
        $this->assertTrue($work[13]->lexem == -1);
        $this->assertTrue($work[13]->countable == false);
        $this->assertTrue($work[14]->lexem == -1);
        $this->assertTrue($work[14]->countable == false);
    }

    public function test_recount_complex_lexems () {
    	$lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $work = array();
        $lexems[] = 'abc';
        $lexems[] = 'def';

        $stringoperations[] = 'insertlexem:0:123';
        $stringoperations[] = 'insert:1:1:f';
        $stringoperations[] = 'movelexem:2:1';

        $source = $lexems;
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string ($lexems, $objectoperations);
        $work = qtype_correctwriting_recount_indexes ($objectoperations, $source);

        $this->assertTrue($work[0]->lexem == 0);
        $this->assertTrue($work[0]->operationname == 'insertlexem');
        $this->assertTrue($work[0]->symbols == '123');
        $this->assertTrue($work[1]->lexem == 0);
        $this->assertTrue($work[2]->lexem == 0);
        $this->assertTrue($work[3]->lexem == 1);
        $this->assertTrue($work[3]->operationname == 'insertlexem');
        $this->assertTrue($work[3]->symbols == 'def');
        $this->assertTrue($work[4]->lexem == 1);
        $this->assertTrue($work[5]->lexem == 1);
        $this->assertTrue($work[6]->lexem == 2);
        $this->assertTrue($work[7]->lexem == 2);
        $this->assertTrue($work[7]->operationname == 'insert');
        $this->assertTrue($work[7]->symbols == 'f');
        $this->assertTrue($work[8]->lexem == 2);
        $this->assertTrue($work[9]->lexem == 2);
        $this->assertTrue($work[10]->lexem == -1);
        $this->assertTrue($work[10]->operationname == 'movelexem');
        $this->assertTrue($work[11]->lexem == -1);
        $this->assertTrue($work[12]->lexem == -1);
    }



    public function test_generate_blocks_1high_1low () {

    	$lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $work = array();
        $lexems[] = 'abc';
        $lexems[] = 'def';
        $lexems[] = '123';

        $stringoperations[] = 'insert:0:1:T';
        $stringoperations[] = 'change:1:2:h';
        $stringoperations[] = 'delete:2:1';

        $source = $lexems;
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string ($lexems, $objectoperations);
        $work = qtype_correctwriting_recount_indexes ($objectoperations, $source);
        $blocks = qtype_correctwriting_generate_blocks ($work, $source, $lexems);
        
        $this->assertTrue(count($blocks) == 3);
        $this->assertTrue(count($blocks[0]->subblockhigh) == 1);
        $this->assertTrue(count($blocks[1]->subblockhigh) == 1);
        $this->assertTrue(count($blocks[2]->subblockhigh) == 1);
        $this->assertTrue(count($blocks[0]->subblocklow) == 1);
        $this->assertTrue(count($blocks[1]->subblocklow) == 1);
        $this->assertTrue(count($blocks[2]->subblocklow) == 1);
        $this->assertTrue($blocks[0]->subblockhigh[0]->symbols == 'a  bc');
        $this->assertTrue($blocks[0]->subblocklow[0]->symbols == 'aTbc');
        $this->assertTrue($blocks[1]->subblockhigh[0]->symbols == 'def');
        $this->assertTrue($blocks[1]->subblocklow[0]->symbols == 'deh');
        $this->assertTrue($blocks[2]->subblockhigh[0]->symbols == '123');
        $this->assertTrue($blocks[2]->subblocklow[0]->symbols == '13');
    }

    public function test_generate_blocks_1high_much_low () {
        
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $work = array();
        $lexems[] = 'abc';
        $lexems[] = 'def';

        $stringoperations[] = 'space:0:1';
        $stringoperations[] = 'insertlexem:1:1';
        $stringoperations[] = 'movelexem:3:1';

        $source = $lexems;
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string ($lexems, $objectoperations);
        $work = qtype_correctwriting_recount_indexes ($objectoperations, $source);
        $blocks = qtype_correctwriting_generate_blocks ($work, $source, $lexems);
        
        $this->assertTrue(count($blocks) == 2);
        $this->assertTrue(count($blocks[0]->subblockhigh) == 2);
        $this->assertTrue(count($blocks[1]->subblockhigh) == 1);
        $this->assertTrue(count($blocks[0]->subblocklow) == 4);
        $this->assertTrue(count($blocks[1]->subblocklow) == 1);
        $this->assertTrue($blocks[0]->subblockhigh[0]->symbols == 'a');
        $this->assertTrue($blocks[0]->subblockhigh[1]->symbols == 'bc');
        $this->assertTrue($blocks[0]->subblocklow[0]->symbols == 'a');
        $this->assertTrue($blocks[0]->subblocklow[1]->symbols == 'def');
        $this->assertTrue($blocks[0]->subblocklow[2]->symbols == '1');
        $this->assertTrue($blocks[0]->subblocklow[3]->symbols == 'bc');
        $this->assertTrue($blocks[1]->subblockhigh[0]->symbols == 'def');
        $this->assertTrue($blocks[1]->subblocklow[0]->symbols == '');
    }

    public function test_generate_blocks_remake_blocks () {
        
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $work = array();
        $lexems[] = 'abc';
        $lexems[] = 'def';

        $stringoperations[] = 'space:0:1';
        $stringoperations[] = 'deletespace:2';

        $source = $lexems;
        $objectoperations = qtype_correctwriting_get_objects($stringoperations);
        $lexems = qtype_correctwriting_get_result_string ($lexems, $objectoperations);
        $work = qtype_correctwriting_recount_indexes ($objectoperations, $source);
        $blocks = qtype_correctwriting_generate_blocks ($work, $source, $lexems);
        
        $this->assertTrue(count($blocks) == 1);
        $this->assertTrue(count($blocks[0]->subblockhigh) == 3);
        $this->assertTrue(count($blocks[0]->subblocklow) == 2);
        $this->assertTrue($blocks[0]->subblockhigh[0]->symbols == 'a');
        $this->assertTrue($blocks[0]->subblockhigh[1]->symbols == 'bc');
        $this->assertTrue($blocks[0]->subblockhigh[2]->symbols == 'def');
        $this->assertTrue($blocks[0]->subblocklow[0]->symbols == 'a');
        $this->assertTrue($blocks[0]->subblocklow[1]->symbols == 'bcdef');
    }

    public function test_try () {
        
        $lexems = array();
        $stringoperations = array();
        $objectoperations = array();
        $work = array();
        $lexems[] = 'a1cdefkvkkv';
        $lexems[] = 'def';

    
        $stringoperations[] = 'exchange:0:0';

        qtype_correctwriting_draw_picture ($lexems, $stringoperations);
    }                    

  
 }


   